package com.xpqh.ksg.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.xpqh.ksg.common.persistence.dao.JsSysConfigMapper;
import com.xpqh.ksg.common.persistence.model.JsSysConfig;
import com.xpqh.ksg.config.SysConfigContant;
import com.xpqh.ksg.config.properties.WechatProperties;
import com.xpqh.ksg.modular.auth.dto.WechatConfigDTO;
import common.utils.RestTemplateUtil;
import common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
@Slf4j
public class WechatUtil {

    private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
    private static final String JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";

    @Autowired
    private JsSysConfigMapper jsSysConfigMapper;

    @Autowired
    private WechatProperties wechatProperties;

    /**
     * 获取 access_token
     *
     * @return access_token
     * @throws Exception
     */
    public String getAccessToken() throws Exception {
        JsSysConfig jsSysConfig = jsSysConfigMapper.selectConfigValueByConfigKey(SysConfigContant.WECHAT_ACCESSTOKEN_CONFIG_KEY);
        if (null != jsSysConfig && jsSysConfig.getCreateDate().getTime() > System.currentTimeMillis() - 7000L * 1000L) {
            return jsSysConfig.getConfigValue();
        }
        String url = String.format(ACCESS_TOKEN_URL, wechatProperties.getAppid(), wechatProperties.getAppsecret());
        String response = RestTemplateUtil.get(url, null, null);
        JSONObject jsonObject = JSONObject.parseObject(response);
        jsSysConfig.setConfigValue(jsonObject.getString("access_token"));
        jsSysConfigMapper.updateById(jsSysConfig);
        return jsonObject.getString("access_token");
    }

    /**
     * 获取 jsapi_ticket
     *
     * @param accessToken
     * @return jsapi_ticket
     * @throws Exception
     */
    public String getJsapiTicket(String accessToken) throws Exception {
        String url = String.format(JSAPI_TICKET_URL, accessToken);
        String response = RestTemplateUtil.get(url, null, null);
        JSONObject jsonObject = JSONObject.parseObject(response);
        return jsonObject.getString("ticket");
    }

    /**
     * 获取微信配置
     *
     * @param url
     * @return WechatConfigDTO
     */
    public WechatConfigDTO getWechatConfig(String url) {
        try {
            // 获取 access_token
            String accessToken = getAccessToken();
            // 获取 jsapi_ticket
            String jsapiTicket = getJsapiTicket(accessToken);
            // 生成签名
            String nonceStr = UUID.randomUUID().toString().replace("-", "");
            String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
            String signature = StringUtils.getJsSdkSign(nonceStr, jsapiTicket, timestamp, url);

            WechatConfigDTO config = new WechatConfigDTO();
            config.setAppId(wechatProperties.getAppid());
            config.setTimestamp(timestamp);
            config.setNonceStr(nonceStr);
            config.setSignature(signature);
            return config;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取微信小程序手机号
     *
     * @param code 微信小程序手机号授权code
     * @return 手机号
     * @throws Exception
     */
    public String getPhoneNumber(String code) throws Exception {
        // 获取 access_token
        String accessToken = getAccessToken();
        
        // 调用微信接口获取手机号
        String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("code", code);
        
        String response = RestTemplateUtil.post(url, null, requestBody);
        JSONObject jsonObject = JSONObject.parseObject(response);
        
        // 解析返回的JSON，获取手机号
        if (jsonObject.containsKey("phone_info")) {
            JSONObject phoneInfo = jsonObject.getJSONObject("phone_info");
            return phoneInfo.getString("phoneNumber");
        } else {
            throw new Exception("Failed to get phone number: " + jsonObject.getString("errmsg"));
        }
    }

}
